package com.db.williamchart.view;

import com.db.williamchart.ChartContract;
import com.db.williamchart.animation.NoAnimation;
import com.db.williamchart.data.Frame;
import com.db.williamchart.data.Label;
import com.db.williamchart.data.Paddings;
import com.db.williamchart.data.configuration.BarChartConfiguration;
import com.db.williamchart.data.configuration.ChartConfiguration;
import com.db.williamchart.extensions.AttrUtils;
import com.db.williamchart.renderer.BarChartRenderer;
import ohos.agp.components.AttrSet;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.WrongTypeException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class BarChartView extends AxisChartView implements ChartContract.BarView {
    private int barsColor = Color.BLACK.getValue();

    private List<Integer> barsColorsList;

    private float barRadius = 0F;

    private int barsBackgroundColor = -1;

    private float spacing = 10f;

    public BarChartView(Context context) {
        this(context,null);
    }

    public BarChartView(Context context, AttrSet attrSet) {
        this(context, attrSet,"");
    }

    public BarChartView(Context context, AttrSet attrSet, String styleName) {
        super(context, attrSet, styleName);
        init(attrSet);
    }

    private void init(AttrSet attrSet){
        renderer = new BarChartRenderer(this,painter,new NoAnimation());

        spacing = (float) AttrUtils.getDimensionFromAttr(attrSet,"chart_spacing",(int) spacing);
        barRadius = (float) AttrUtils.getDimensionFromAttr(attrSet,"chart_barsRadius",(int) barRadius);
        barsColor = AttrUtils.getColorFromAttr(attrSet,"chart_barsColor",barsColor);
        barsBackgroundColor = AttrUtils.getColorFromAttr(attrSet,"chart_barsBackgroundColor",barsBackgroundColor);
        int resourceId = AttrUtils.getIntFromAttr(attrSet,"chart_barsColorsList",-1);
        if (resourceId != -1){
            try {
                int[] intArray = getResourceManager().getElement(resourceId).getIntArray();
                barsColorsList = new ArrayList<>();
                for (int a : intArray){
                    barsColorsList.add(a);
                }
            } catch (IOException | NotExistException | WrongTypeException e) {
                barsColorsList = new ArrayList<>();
            }
        }
    }

    @Override
    public void postInvalidate() {
        invalidate();
    }

    @Override
    public void drawLabels(List<Label> xLabels) {
        painter.prepare((float)labelsSize,labelsColor, Paint.Style.FILL_STYLE,null,null,null,labelsFont);
        labels.draw(canvas,painter.getPaint(),xLabels);
    }

    @Override
    public void drawGrid(Frame innerFrame, List<Float> xLabelsPositions, List<Float> yLabelsPositions) {
        grid.draw(canvas, innerFrame, xLabelsPositions, yLabelsPositions);
    }

    @Override
    public void drawDebugFrame(List<Frame> frames) {
        painter.prepare(null,-0x1000000, Paint.Style.STROKE_STYLE,null,null,null,null);
        for (Frame frame : frames){
            canvas.drawRect(frame.toRectFloat(),painter.getPaint());
        }
    }

    @Override
    public void drawBars(List<Frame> frames) {
        if (barsColorsList == null){
            barsColorsList = new ArrayList<>();
            for (Frame ignored : frames) {
                barsColorsList.add(barsColor);
            }
        }
        if (barsColorsList.size() != frames.size()){
            throw new IllegalArgumentException("Colors provided do not match the number of datapoints.");
        }
        int index = 0;
        for (Frame frame : frames){
            painter.prepare(null,barsColorsList.get(index), Paint.Style.FILL_STYLE,null,null,null,null);
            canvas.drawRoundRect(frame.toRectFloat(),barRadius,barRadius,painter.getPaint());
            index++;
        }
    }

    @Override
    public void drawBarsBackground(List<Frame> frames) {
        painter.prepare(null,barsBackgroundColor, Paint.Style.FILL_STYLE,null,null,null,null);
        for (Frame frame : frames){
            canvas.drawRoundRect(frame.toRectFloat(),barRadius,barRadius,painter.getPaint());
        }
    }
    private BarChartConfiguration chartConfiguration;

    @Override
    ChartConfiguration getChartConfiguration() {
        if (chartConfiguration == null){
            chartConfiguration = new BarChartConfiguration(
                    getWidth(),
                    getHeight(),
                    new Paddings(
                            getPaddingLeft(),
                            getPaddingTop(),
                            getPaddingRight(),
                            getPaddingBottom()
                    ),
                    axis,
                    (float) labelsSize,
                    scale,
                    labelsFormatter,
                    barsBackgroundColor,
                    spacing
            );
        }

        return chartConfiguration;
    }

    public void setBarsColor(int barsColor) {
        this.barsColor = barsColor;
    }

    public void setBarsColorsList(List<Integer> barsColorsList) {
        this.barsColorsList = barsColorsList;
    }

    public void setBarRadius(float barRadius) {
        this.barRadius = barRadius;
    }

    public void setBarsBackgroundColor(int barsBackgroundColor) {
        this.barsBackgroundColor = barsBackgroundColor;
    }

    public void setSpacing(float spacing) {
        this.spacing = spacing;
    }
}
